﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PatientInformationExtract.MainInterface.Views;
using PatientInformationExtract.MainInterface.Models;
using PatientInformationExtract.Components;
using System.Windows;
using System.Windows.Input;
using System.Data;
using System.Collections.ObjectModel;
using System.Windows.Threading;
using System.Windows.Controls;
using System.Threading;

namespace PatientInformationExtract.MainInterface.ViewModels
{
    public class PatientInformationExtractViewModel : WindowViewModelBase
    {
        private string _patientID;
        public string PatientID
        {
            get
            {
                return this._patientID;
            }
            set
            {
                if (this._patientID != value)
                {
                    this._patientID = value;
                    NotifyPropertyChanged("PatientID");
                }
            }
        }

        private string _patientName;
        public string PatientName
        {
            get
            {
                return this._patientName;
            }
            set
            {
                if (this._patientName != value)
                {
                    this._patientName = value;
                    NotifyPropertyChanged("PatientName");
                }
            }
        }

        private string _visitID;
        public string VisitID
        {
            get
            {
                return this._visitID;
            }
            set
            {
                if (this._visitID != value)
                {
                    this._visitID = value;
                    NotifyPropertyChanged("VisitID");
                }
            }
        }

        private string _examID;
        public string ExamID
        {
            get
            {
                return this._examID;
            }
            set
            {
                if (this._examID != value)
                {
                    this._examID = value;
                    NotifyPropertyChanged("ExamID");
                }
            }
        }

        private string _patientGender;
        public string PatientGender
        {
            get
            {
                return this._patientGender;
            }
            set
            {
                if (this._patientGender != value)
                {
                    this._patientGender = value;
                    NotifyPropertyChanged("PatientGender");
                }
            }
        }

        private string _patientAge;
        public string PatientAge
        {
            get { return this._patientAge; }
            set
            {
                if (this._patientAge != value)
                {
                    this._patientAge = value;
                    NotifyPropertyChanged("PatientAge");
                }
            }
        }

        private string _folderPath;
        public string FolderPath
        {
            get { return this._folderPath; }
            set
            {
                if (_folderPath != value)
                {
                    this._folderPath = value;
                    NotifyPropertyChanged("FolderPath");
                }
            }
        }

        private string _systemStatus;
        public string SystemStatus
        {
            get { return this._systemStatus; }
            set
            {
                if (this._systemStatus != value)
                {
                    this._systemStatus = value;
                    base.NotifyPropertyChanged("SystemStatus");
                }
            }
        }

        private string _systemTime;
        public string SystemTime
        {
            get { return _systemTime; }
            set
            {
                if (_systemTime != value)
                {
                    _systemTime = value;
                    NotifyPropertyChanged("SystemTime");
                }
            }
        }

        private ObservableCollection<PatientListTreeItem> _patientListView;
        public ObservableCollection<PatientListTreeItem> PatientListView
        {
            get { return this._patientListView; }
            set
            {
                if (this._patientListView != value)
                {
                    this._patientListView = value;
                    base.NotifyPropertyChanged("PatientListView");
                }
            }
        }

        private List<string> _diagnosis;
        public List<string> Diagnosis
        {
            get { return this._diagnosis; }
            set
            {
                if (this._diagnosis != value)
                {
                    this._diagnosis = value;
                    NotifyPropertyChanged("Diagnosis");
                }
            }
        }

        private DataTable _observationTable;
        public DataTable ObservationTable
        {
            get { return this._observationTable; }
            set
            {
                if (this._observationTable != value)
                {
                    this._observationTable = value;
                    NotifyPropertyChanged("ObservationTable");
                }
            }
        }

        private DataTable _medicalInterventionTable;
        public DataTable MedicalInterventionTable
        {
            get { return this._medicalInterventionTable; }
            set
            {
                if (this._medicalInterventionTable != value)
                {
                    this._medicalInterventionTable = value;
                    NotifyPropertyChanged("MedicalInterventionTable");
                }
            }
        }

        private ObservableCollection<ICheckableItem> _directoryTree;
        public ObservableCollection<ICheckableItem> DirectoryTree
        {
            get { return this._directoryTree; }
            set
            {
                if (this._directoryTree != value)
                {
                    this._directoryTree = value;
                    base.NotifyPropertyChanged("DirectoryTree");
                }
            }
        }

        private bool _isDictionaryManageEnabled;
        public bool IsDictionaryManageEnabled
        {
            get { return this._isDictionaryManageEnabled; }
            set
            {
                if (this._isDictionaryManageEnabled != value)
                {
                    this._isDictionaryManageEnabled = value;
                    base.NotifyPropertyChanged("IsDictionaryManageEnabled");
                }
            }
        }

        private MultiTypeValue _isBusy = new MultiTypeValue();
        public MultiTypeValue IsBusy { get { return this._isBusy; } }

        private ICommand _exportCommand;
        public ICommand ExportCommand { get { return this._exportCommand; } }

        private ICommand _aboutCommand;
        public ICommand AboutCommand { get { return this._aboutCommand; } }

        private ICommand _confirmCommand;
        public ICommand ConfirmCommand { get { return this._confirmCommand; } }

        private ICommand _dictionaryManageCommand;
        public ICommand DictionaryManageCommand { get { return this._dictionaryManageCommand; } }

        public PatientInformationExtractViewModel(WindowViewModelBase parent)
        {
            if (Singleton<MainInterfaceModel>.Instance.IsInitialized)
            {
                this.SystemStatus = "Initializing succeeded.";
            }

            this.DirectoryTree = Models.DirectoryTree.InitRoot();

            this._exportCommand = new Command(new Action<object>(this.Export));
            this._aboutCommand = new Command(new Action<object>(this.About));
            this._confirmCommand = new Command(new Action<object>(this.Confirm));

            DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer(DispatcherPriority.Send);
            dispatcherTimer.Tick += new EventHandler(OnTimedEvent);
            dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
            dispatcherTimer.Start();

            base._parent = parent;
            WindowInitialize();
        }

        protected override void WindowInitialize()
        {
            base.WindowInitialize();
            base._window = new PatientInformationExtractWindow();
            base._window.DataContext = this;
        }

        public override void Show()
        {
            if (Singleton<MainInterfaceModel>.Instance.IsInitialized)
            {
                base.Show();
            }
        }

        public override bool? ShowDialog()
        {
            if (Singleton<MainInterfaceModel>.Instance.IsInitialized)
            {
                return base.ShowDialog();
            }
            return null;
        }

        private void OnTimedEvent(object sender, EventArgs e)
        {
            this.SystemTime = string.Format("{0:F}", DateTime.Now);
        }

        public void Export(object o)
        {
            if (Singleton<MainInterfaceModel>.Instance.PatientList.Count != 0)
            {
                ExportViewModel exportVM = new ExportViewModel(this, this.PatientListView);
                exportVM.ShowDialog();
            }
            else
            {
                MessageBox.Show("Can't find any patient folder.");
            }
        }

        public void About(object o)
        {
            WPFAboutBox1 about = new WPFAboutBox1(base._window);
            about.ShowDialog();
        }

        public void Confirm(object o)
        {
            base.MultiTypeValueChange(this._isBusy, MultiTypeValue.Command.TrueVisible, "IsBusy");
            ThreadPool.QueueUserWorkItem(RetrieveFile);
        }

        private void RetrieveFile(object o)
        {
            RetrieveFileModel retrieveFileModel = new RetrieveFileModel(this.DirectoryTree);
            retrieveFileModel.RetrieveCheckedPatientList();
            base.MultiTypeValueChange(this._isBusy, MultiTypeValue.Command.FalseHidden, "IsBusy");
            retrieveFileModel.PatientListAfterProcess(RetrieveFileModel.RetrieveFileOption.AddRepeatedPatientAfterQuestion);
            this.SystemStatus = "Find " + retrieveFileModel.PatientList.Count.ToString() + " patient folders.";
            Singleton<MainInterfaceModel>.Instance.PatientList = retrieveFileModel.PatientList;
            this.PatientListView = retrieveFileModel.PatientListView;
        }
    }
}
